
package com.hlkj.pay.controller.merchant;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.bean.BeanUtil;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.pay.app.payment.IMerchantPaymentAppService;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.controller.BaseController;
import com.hlkj.pay.dto.merchant.MerchantAcctBalanceDto;
import com.hlkj.pay.dto.merchant.MerchantPaymentPageStatisticsDto;
import com.hlkj.pay.dto.payment.MerchantPaymentDetailDto;
import com.hlkj.pay.dto.payment.MerchantPaymentDto;
import com.hlkj.pay.dto.payment.MerchantPaymentPageDto;
import com.hlkj.pay.dto.payment.MerchantPaymentPageQueryDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDO;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDetailDO;
import com.hlkj.pay.service.payment.IMerchantPaymentService;
import com.hlkj.pay.service.payment.IMerchantPaymentStatisticsService;
import com.hlkj.pay.vo.merchant.req.payment.MerchantPaymentApproveReq;
import com.hlkj.pay.vo.merchant.req.payment.MerchantPaymentDetailReq;
import com.hlkj.pay.vo.merchant.req.payment.MerchantPaymentFileReq;
import com.hlkj.pay.vo.merchant.req.payment.MerchantPaymentReq;
import com.hlkj.pay.vo.merchant.resp.payment.MerchantPaymentDetailPageResp;
import com.hlkj.pay.vo.merchant.resp.payment.MerchantPaymentResp;
import com.hlkj.pay.vo.merchant.resp.payment.PagePaymentAndStatisticsResp;
import com.hlkj.pay.vo.order.resp.PayOrderDetailResp;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;

/**
 * @author HlpayTeam
 * @date 2024/11/20 13:46
 */
@Tag(name = "商户代付管理")
@RestController
@RequestMapping("/v1/merchant/payment")
@Slf4j
@RequiredArgsConstructor
public class MerchantPaymentController extends BaseController {

    private final IMerchantPaymentService merchantPaymentService;

    private final IMerchantPaymentAppService merchantPaymentAppService;

    private final IMerchantPaymentStatisticsService paymentStatisticsService;

    @Operation(summary = "代付列表")
    @GetMapping("/page")
    public CommonResult<PageResult<MerchantPaymentResp>> queryPage(MerchantPaymentReq merchantPaymentReq) {
        MerchantPaymentPageQueryDto merchantPaymentPageQueryDto = BeanUtil.copyProperties(merchantPaymentReq, MerchantPaymentPageQueryDto.class);
        merchantPaymentPageQueryDto.setPageNo(merchantPaymentReq.getPageNo());
        merchantPaymentPageQueryDto.setPageSize(merchantPaymentReq.getPageSize());
        // merchantPaymentPageQueryDto.setPaymentType(CommonEnum.YES_NO_TYPE.NO.getCode());
        processQueryDate(merchantPaymentReq, merchantPaymentPageQueryDto);
        PageResult<MerchantPaymentPageDto> pageResult = merchantPaymentService.queryPage(merchantPaymentPageQueryDto);
        List<MerchantPaymentPageDto> list = pageResult.getList();
        if (CollectionUtils.isEmpty(list)) {
            return buildPageResult(pageResult, Collections.emptyList());
        }
        List<MerchantPaymentResp> merchantPaymentResps = BeanUtil.copyToList(list, MerchantPaymentResp.class);
        processProvideList(merchantPaymentResps);
        merchantPaymentAppService.syncAll(list);
        return buildPageResult(pageResult, merchantPaymentResps);
    }

    @Operation(summary = "代付明细page")
    @GetMapping("/detail/page")
    public CommonResult<PagePaymentAndStatisticsResp> detailPage(MerchantPaymentReq merchantPaymentReq) {
        PagePaymentAndStatisticsResp resp;
        MerchantPaymentPageQueryDto merchantPaymentPageQueryDto = BeanUtil.copyProperties(merchantPaymentReq, MerchantPaymentPageQueryDto.class);
        merchantPaymentPageQueryDto.setPageNo(merchantPaymentReq.getPageNo());
        merchantPaymentPageQueryDto.setPageSize(merchantPaymentReq.getPageSize());
        processQueryDate(merchantPaymentReq, merchantPaymentPageQueryDto);
        PageResult<MerchantPaymentDetailDto> pageResult = merchantPaymentService.queryDetailPage(merchantPaymentPageQueryDto);
        List<MerchantPaymentDetailDto> list = pageResult.getList();
        if (CollectionUtils.isEmpty(list)) {
            CommonResult<PageResult<PayOrderDetailResp>> result = buildPageResult(pageResult, Collections.emptyList());
            resp = cn.hutool.core.bean.BeanUtil.copyProperties(result.getData(), PagePaymentAndStatisticsResp.class);
            resp.setStatisticsDO(new MerchantPaymentPageStatisticsDto());
            return CommonResult.success(resp);
        }

        List<MerchantPaymentDetailPageResp> paymentDetailPageResps = BeanUtil.copyToList(list, MerchantPaymentDetailPageResp.class);
        processProvideList(paymentDetailPageResps);
        CommonResult<PageResult<MerchantPaymentDetailPageResp>> result = buildPageResult(pageResult, paymentDetailPageResps);
        resp = BeanUtil.copyProperties(result.getData(), PagePaymentAndStatisticsResp.class);
        resp.setStatisticsDO(merchantPaymentService.merchantPaymentStatistics(merchantPaymentPageQueryDto));
        return CommonResult.success(resp);
    }

    @Operation(summary = "代付明细")
    @GetMapping("/detail")
    public CommonResult<MerchantPaymentDetailPageResp> detail(@RequestParam(name = "detailPaymentId", required = false) String detailPaymentId) {
        MerchantPaymentDetailDO merchantPaymentDetailDO = merchantPaymentService.queryPaymentDetail(detailPaymentId);
        if (merchantPaymentDetailDO == null) {
            return CommonResult.success();
        }
        MerchantPaymentDetailPageResp merchantPaymentDetailPageResp = BeanUtil.copyProperties(merchantPaymentDetailDO, MerchantPaymentDetailPageResp.class);
        MerchantPaymentDO merchantPaymentDO = merchantPaymentService.queryDetail(merchantPaymentDetailDO.getPaymentId());
        merchantPaymentDetailPageResp.setMessage(merchantPaymentDetailDO.getRemark());
        if(merchantPaymentDO==null){
            merchantPaymentDetailPageResp.setEntryType(merchantPaymentDO.getEntryType());
            merchantPaymentDetailPageResp.setPayeeType(merchantPaymentDO.getPayeeType());
            merchantPaymentDetailPageResp.setRemark("");
        } else {
            merchantPaymentDetailPageResp.setRemark(merchantPaymentDO.getRemark());
        }
        return CommonResult.success(merchantPaymentDetailPageResp);
    }

    @Operation(summary = "代付订单重新发起")
    @PostMapping("/detail/save")
    public CommonResult<Void> detail(@RequestBody MerchantPaymentDetailPageResp merchantPaymentDetailPageResp) {
        return merchantPaymentAppService.submitDetail(merchantPaymentDetailPageResp);
    }

    @Operation(summary = "批次状态查询")
    @GetMapping("/status")
    public CommonResult<Void> syncStatus(@RequestParam(name = "paymentId") String paymentId) {
        MerchantPaymentDto merchantPaymentDto = merchantPaymentService.queryDetailDto(paymentId);
        if (!MerchantEnum.PROCESS_STATUS.DOING.getCode().equals(merchantPaymentDto.getStatus())) {
            return CommonResult.error(MerchantResultCode.MERCHANT_PAYMENT_CANNOT_SYNC);
        }
        merchantPaymentAppService.queryDetailList(paymentId);
        return CommonResult.success();
    }

    @Operation(summary = "详情状态查询")
    @GetMapping("/detail/status")
    public CommonResult<Void> syncDetailStatus(@RequestParam(name = "detailPaymentId") String detailPaymentId) {

        return merchantPaymentAppService.syncDetailStatus(detailPaymentId);
    }

    @Operation(summary = "代付凭证")
    @GetMapping("/proof")
    public CommonResult<String> queryProof(@RequestParam(name = "paymentId", required = false) String paymentId) {
        return merchantPaymentAppService.queryProof(paymentId, false);
    }

    @Operation(summary = "代付凭证重新生成")
    @GetMapping("/proof/regenerate")
    public CommonResult<String> regenerateProof(@RequestParam(name = "paymentId", required = false) String paymentId) {
        return merchantPaymentAppService.queryProof(paymentId, true);
    }

    @Operation(summary = "代付明细凭证")
    @GetMapping("/proof/detail")
    public CommonResult<String> queryDetailProof(@RequestParam(name = "detailPaymentId", required = false) String detailPaymentId) {
        return merchantPaymentAppService.queryDetailProof(detailPaymentId);
    }

    @Operation(summary = "代付账号余额查询")
    @GetMapping("/account")
    public CommonResult<List<MerchantAcctBalanceDto>> account(
            @Parameter(name = "mchChannelCode", description = "子通道编码", required = true) @RequestParam(name = "mchChannelCode") String mchChannelCode,
            @Parameter(name = "acctTypeList", description = "1-表示人民币账户 2-代收账户 3-代付账户", required = false) @RequestParam(name = "acctTypeList", required = false) List<Integer> acctTypeList) {
        return merchantPaymentAppService.queryAccount(mchChannelCode, acctTypeList);
    }

    @Operation(summary = "代付审核")
    @PostMapping("/approve")
    public CommonResult<Void> approve(@Validated @RequestBody MerchantPaymentApproveReq merchantPaymentApproveReq) {
        return merchantPaymentAppService.approve(merchantPaymentApproveReq);
    }

    @Operation(summary = "通过文件提交代付申请")
    @PostMapping("/add/file")
    public CommonResult<String> uploadFile(@Validated @RequestBody MerchantPaymentFileReq merchantPaymentFileReq) {
        return merchantPaymentAppService.addFilePayment(merchantPaymentFileReq);
    }

    @Operation(summary = "手动提交代付申请")
    @PostMapping("/add")
    public CommonResult<Void> addPayment(@Validated @RequestBody MerchantPaymentDetailReq merchantPaymentDetailReq) {
        return merchantPaymentAppService.addPayment(merchantPaymentDetailReq);
    }

//     @Operation(summary = "手动修改代付明细")
//     @PostMapping("/update")
//     public CommonResult<Void> addPayment(@Validated @RequestBody MerchantPaymentDetailUpdateReq merchantPaymentDetailUpdateReq) {
//         return merchantPaymentAppService.updatePayment(merchantPaymentDetailUpdateReq);
//     }


}

